// 这里面存放的就是 vuex 相关的核心代码
import Vue from 'vue'
import Vuex from 'vuex'

// 插件安装
Vue.use(Vuex)

// 创建仓库
const store = new Vuex.Store({
  // 1 通过state可以提供数据 state 状态, 即数据, 类似于vue组件中的data,
  // 区别:
  //   1.data 是组件自己的数据,
  //   2.state 中的数据整个vue项目的组件都能访问到
  state: {
    title: '大标题',
    count: 101,
    list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  },
  // 2 通过mutations可以提供修改数据的方法
  mutations: {
    // 所有mutations的函数 第一个参数都是state
    addCount (state) {
      // 修改数据 - 在组件里面通过commit提交
      state.count += 1
    },
    addFive (state) {
      // 修改数据 - 在组件里面通过commit提交
      state.count += 5
    },
    changeTitle (state) {
      state.title = '小标题'
    },
    handleAddWithParam (state, n) {
      // 修改数据 - 在组件里面通过commit提交
      state.count += n
    },
    changeTitleWithParam (state, input1) {
      state.title = input1
    },
    handleSubWithParam (state, n) {
      state.count -= n
    },
    changeCount (state, newVal) {
      state.count = newVal
    }
  },
  // 3 actions处理异步
  // 注意不能直接操作state 操作state还是需要commit mutation
  actions: {
    // context 上下文 (此处未分模块，可以当成store仓库)
    // context.commit(mutation名字 ，额外参数)
    changeCountAsync (context, num) {
      // 这里是setTimeout模拟异步，以后大部分场景是发请求
      setTimeout(() => {
        context.commit('changeCount', num)
      }, 1000)
    }
  },
  // 4 getters 类似于计算属性
  getters: {
    // 注意点:
    // 1.形参第一个参数，就是state
    // 2.必须有返回值，返回值就是getters的值
    filterList (state) {
      return state.list.filter(item => item > 5)
    }
  }
})

/*
核心概念1 - state 状态
  目标:明确如何给仓库提供数据，如何使用库的数据
  使用数据
    1 通过 store 直接访问
      获取 store:
        模板中: {{ $store.state.xxx}}
        组件逻辑中:this.$store.state.xxx
        JS模块中:store.state.xxx
    2 通过辅助函数
      mapState是辅助函数，帮助我们把store中的数据自动映射到组件的计算属性中
        import{mapState ]from 'vuex  //1 导入mapState
        mapState(['count'])          //2 数组方式引入state
        computed: {                  //3 展开运算符映射
            ...mapState(['count'])
        }
-------------------------------------------
核心概念2 - mutations
    this.$store.state.count (错误写法)
  目标:明确 vuex同样遵循单向数据流，组件中不能直接修改仓库的数据
      掌握mutations的操作流程，来修改state 数据。
      (state数据的修改只能通过mutations)
    1.定义mutations对象，对象中存放修改 state 的方法
        const store = new Vuex.Store({
          state:{
            count: 0
          },
          // 定义mutations
          mutations:{
            // 第一个参数是当前store的state属性
            addCount (state) {
                state.count += 1
            }
          }
        }
    2.组件中提交调用mutations
       this.$store.commit('addCount')
    3.mutations可以传递参数
      (1)提供mutation函数(带参数- 提交载荷 payload)
        mutations:{
          addCount (state, n) {
            state.count += n
          }
        }
      (2)提供mutation函数(带参数- 提交载荷 payload)
          this.$store.commit('addCount', 参数)
    -----------------------------------------
    辅助函数: mapMutations
      目标:掌握辅助函数mapMutations，映射方法
      mapMutations和 mapState很像，它是把位于mutations中的方法提取了出来，映射到组件methods中
-------------------------------------------
核心概念3-actions
  目标:明确actions的基本语法，处理异步操作
  需求:一秒钟之后，修改state的 count成666。
  说明: mutations 必须是同步的(便于监测数据变化，记录调试)
  1 提供action 方法
    actions: {
      setAsyncCount (context, num) {
        //一秒后，给一个数，去修改
        numsetTimeout(() => {
          context.commit('changeCount', num)
        }，1000)
      }
    }
  2 页面中 dispatch 调用
    this.$store.dispatch('setAsyncCount'，200)
    -----------------------------------------------
    辅助函数 - mapActions
    目标:掌握辅助函数mapActions，映射方法
    mapActions是把位于actions中的方法提取了出来，映射到组件methods中
-----------------------------------------------
核心概念 - getters
  目标:掌握核心概念 getters 的基本语法(类似于计算属性)
  说明:除了state之外，有时我们还需要从state中派生出一些状态，这些状态是依赖state的，此时会用到getters

  例如:state中定义了list，为 1-10 的数组，组件中，需要显示所有大于5的数据
    state: {
      list: [1，2，3，4，5，6，7，8，9，10]
    }
   1.定义 getters
    getters: {
      // 注意:
      // (1) getters函数的第一个参数是state
      // (2) getters函数必须要有返回值
      filterList (state) {
        return state.list.filter(item => item > 5)
      }
    }
   2.访问getters
    1) 通过 store 访问 getters
      {{ $store.getters.filterList }}
    2)通过辅助函数 mapGetters 映射
      computed: {
        ...mapGetters(['filterList'])
      }
      使用 {{ filterList }}

*/

// 导出给main.js使用
export default store
